﻿ #region Disclaimer/Info
 
 /////////////////////////////////////////////////////////////////////////////////////////////////
 //
 //   File:		DexterControllerBase.cs
 //   Website:		http://dexterblogengine.com/
 //   Authors:		http://dexterblogengine.com/About.ashx
 //   Rev:		1
 //   Created:		19/01/2011
 //   Last edit:		19/01/2011
 //   License:		GNU Library General Public License (LGPL)
 // 
 //   For updated news and information please visit http://dexterblogengine.com/
 //   Dexter is hosted to Codeplex at http://dexterblogengine.codeplex.com
 //   For any question contact info@dexterblogengine.com
 //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 #endregion

using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.SessionState;
using Dexter.Domain.Model;
using Dexter.Logger.Contracts;
using Dexter.Services;
using Dexter.Web.Mvc.Results;
using Dexter.Web.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace Dexter.Web.Mvc.Controllers {
	/// <summary>
	/// 	Defines the base class for all MVC Controllers.
	/// </summary>
	[SessionState ( SessionStateBehavior.Default )]
	public abstract class DexterControllerBase : Controller {
		readonly IConfigurationService configurationService;
		readonly IUrlBuilder urlBuilder;
		readonly IWebUtils webUtils;

		protected DexterControllerBase ( IConfigurationService configurationService , IWebUtils webUtils , ILogger logger , IUrlBuilder urlBuilder ) {
			this.configurationService = configurationService;
			this.urlBuilder = urlBuilder;
			this.webUtils = webUtils;
			Logger = logger;
		}

		public IWebUtils WebUtils {
			get { return webUtils; }
		}

		/// <summary>
		/// Initializes data that might not be available when the constructor is called.
		/// </summary>
		/// <param name="requestContext">The HTTP context and route data.</param>
		protected override void Initialize ( RequestContext requestContext ) {
			base.Initialize ( requestContext );

			Thread.CurrentThread.CurrentCulture = configurationService.Configuration.Culture;

			base.Initialize ( requestContext );
		}

		/// <summary>
		/// Called when an unhandled exception occurs in the action.
		/// </summary>
		/// <param name="filterContext">Information about the current request and action.</param>
		protected override void OnException(ExceptionContext filterContext)
		{
			HttpException httpException = filterContext.Exception as HttpException;

			if (httpException != null && httpException.GetHttpCode() == 404)
				Logger.Info(httpException.Message, httpException);
			else if (filterContext.Exception is HttpAntiForgeryException)
				Logger.Info(filterContext.Exception.Message, filterContext.Exception);
			else
				Logger.Error("Generic Exception", filterContext.Exception);
		}

		/// <summary>
		/// 	Return an instance of <see cref = "ILogger" />.
		/// </summary>
		protected ILogger Logger { get; private set; }

		/// <summary>
		/// 	Gets the configuration.
		/// </summary>
		/// <value>The configuration.</value>
		public SiteConfiguration Configuration {
			get { return configurationService.Configuration; }
		}

		/// <summary>
		/// 	Gets the configuration service.
		/// </summary>
		/// <value>The configuration service.</value>
		public IConfigurationService ConfigurationService {
			get { return configurationService; }
		}

		/// <summary>
		/// 	Gets the URL builder.
		/// </summary>
		/// <value>The URL builder.</value>
		public IUrlBuilder UrlBuilder {
			get { return urlBuilder; }
		}

		/// <summary>
		/// Redirects to the specified action using the action name and route dictionary.
		/// </summary>
		/// <param name="actionName">The name of the action.</param>
		/// <param name="controllerName">The name of the controller</param>
		/// <param name="routeValues">The parameters for a route.</param>
		/// <returns>The redirect result object.</returns>
		public new RedirectToRouteResult RedirectToAction(string actionName, string controllerName, object routeValues) {
			return base.RedirectToAction ( actionName , controllerName , routeValues );
		}

		/// <summary>
		/// Jsons the specified data.
		/// </summary>
		/// <param name="data">The data.</param>
		/// <returns></returns>
		protected new JsonNetResult Json ( object data ) {
			var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver ( ) };
			return new JsonNetResult ( data, settings );
		}

		/// <summary>
		/// HTTPs the not modified.
		/// </summary>
		/// <returns></returns>
		protected HttpStatusCodeResult HttpNotModified ( ) {
			return new HttpStatusCodeResult ( 304 );
		}

	}
}
